<?php
/**
 * Samble XML-RPC
 * Samble XML-RPC client class file.
 *
 * @author Lim Afriyadi
 * @package Samble
 * @subpackage xmlrpc
 * @version pre-alpha
 * @license GNU/GPL.
 */
class Xmlrpc_Client
{
    /**
     * The class single instance.
     * @static
     * @var object
     */
    private static $oInstance;
    /**
     * XML-RPC server host.
     * @var string
     */
    private $sHost;
    /**
     * XML-RPC server path.
     * @var string
     */
    private $sPath;
    /**
     * XML-RPC server port.
     * @var int
     */
    private $iPort;
    /**
     * Array of XML-RPC requests.
     * @var array
     */
    private $aRequest;

    private function __construct()
    {
        $this->sHost    = '127.0.0.1';
        $this->sPath    = $_SERVER['PHP_SELF'];
        $this->iPort    = '80';
        $this->aRequest = array();
    }
    /**
     * Grab the class single instance.
     * @static
     */
    public static function getInstance()
    {
        if(!self::$oInstance)
        {
            self::$oInstance = new Xmlrpc_Client();
        }
        return self::$oInstance;
    }
    /**
     * XML-RPC server host setter.
     * @param string $sHost XML-RPC server host
     */
    public function setHost($sHost)
    {
        $this->sHost = $sHost;
    }
    /**
     * XML-RPC server host getter.
     * @return string
     */
    public function getHost()
    {
        return $this->sHost;
    }
    /**
     * XML-RPC server host setter.
     * @param string $sHost XML-RPC server host
     */
    public function setPath($sPath)
    {
        $this->sPath = $sPath;
    }
    /**
     * XML-RPC server port getter.
     * @return string
     */
    public function getPath()
    {
        return $this->sPath;
    }
    /**
     * XML-RPC server port setter.
     * @param int $sHost XML-RPC server host
     */
    public function setPort($iPort)
    {
        $this->iPort = $iPort;
    }
    /**
     * XML-RPC server port getter.
     * @return int
     */
    public function getPort()
    {
        return $this->iPort;
    }
    /**
     * XML-RPC request setter.
     * @param string $sRequest XML-RPC xml request.
     */
    public function setRequest($aRequest)
    {
        $this->aRequest['function']   = $aRequest[0];
        $this->aRequest['parameters'] = $aRequest[1];
    }
    /**
     * XML-RPC request array getter.
     * @return array
     */
    public function getRequest()
    {
        return $this->aRequest;
    }
    /**
     * Clear XML-RPC request array.
     */
    public function clearRequest()
    {
        $this->aRequest = array();
    }
    /**
     * XML-RPC request sender interface.
     *
     * @param string $sFnName
     * @param string $sParam
     * @return object
     */
    public function makeRequest($sFnName,$sParam)
    {
        $this->oRequest = xmlrpc_encode_request($sFnName, $sParam);
        return $this->call($this->sHost, $this->sPath, $this->iPort, $this->oRequest);
    }
    /**
     * Private XML-RPC request sender function.
     *
     * @param string $sHost XML-RPC server host.
     * @param string $sPath XML-RPC server path.
     * @param int $iPort XML-RPC server port.
     * @param object $oRequest XML-RPC request xml.
     * @return object || false
     */
    private function call($sHost, $sPath, $iPort, $oRequest)
    {
        $oSocket = fsockopen($sHost, $iPort, $errno, $errstr);
        if($oSocket)
        {
            $this->sHost = $sHost;
            $this->sPath = $sPath;
            $this->iPort = $iPort;
            $this->oRequest = $oRequest;

            fwrite($oSocket,"POST ".$sPath." HTTP/1.0\r\n");
            fwrite($oSocket,"User_Agent: PHPRPC/1.0\r\n");
            fwrite($oSocket,"Host: ".$sHost."\r\n");
            fwrite($oSocket,"Content-Type: text/xml\r\n");
            fwrite($oSocket,"Content-Length: ".strlen($oRequest)."\r\n");
            fwrite($oSocket,"Accept: */*\r\n");
            fwrite($oSocket,"\r\n");
            fwrite($oSocket,$oRequest."\r\n");
            fwrite($oSocket,"\r\n");
            fwrite($oSocket,'');

            $sHeaders = "";
            while ($str = trim(fgets($oSocket, 4096))) {
                $sHeaders .= "$str\n";
            }

            $sData = "";
            while (!feof($oSocket)) {
                $sData .= fgets($oSocket, 4096);
            }
            
            fclose($oSocket);
            return $sData;
        }
        ErrorHandler::error("Cannot connect to xmlrpc server.");
        return false;
    }
}
?>